package com.example.project.projectspringcloud.service.impl.order;

import com.example.project.projectspringcloud.common.Constants;
import com.example.project.projectspringcloud.common.OperationException;
import com.example.project.projectspringcloud.dao.discountcoupon.DiscountCouponMapper;
import com.example.project.projectspringcloud.dao.order.OrderComboMapper;
import com.example.project.projectspringcloud.dao.order.OrderDetailMapper;
import com.example.project.projectspringcloud.dao.order.OrderMapper;
import com.example.project.projectspringcloud.dao.order.OrderReceiptMapper;
import com.example.project.projectspringcloud.dao.user.UserMapper;
import com.example.project.projectspringcloud.dao.video.VideoMapper;
import com.example.project.projectspringcloud.entity.Key;
import com.example.project.projectspringcloud.entity.Page;
import com.example.project.projectspringcloud.entity.discountcoupon.DiscountCoupon;
import com.example.project.projectspringcloud.entity.order.*;
import com.example.project.projectspringcloud.entity.user.User;
import com.example.project.projectspringcloud.entity.video.Video;
import com.example.project.projectspringcloud.service.BaseService;
import com.example.project.projectspringcloud.service.order.OrderDetailService;
import com.example.project.projectspringcloud.service.order.OrderReceiptService;
import com.example.project.projectspringcloud.service.order.OrderService;
import com.example.project.projectspringcloud.utils.StringUtil;
import com.example.project.projectspringcloud.utils.WebUtil;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 订单 Service
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl extends BaseService<Order, OrderMapper> implements OrderService {

    @Autowired
    private MessageSource messageSource;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderReceiptMapper orderReceiptMapper;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderReceiptService orderReceiptService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderComboMapper orderComboMapper;

    @Autowired
    private DiscountCouponMapper discountCouponMapper;

    @Autowired
    private VideoMapper videoMapper;

    @Override
    public Order get(Order order) {
        order = super.mapper.selectOne(order);
        if (Optional.ofNullable(order).isPresent()) {
            // 设置订单下单用户
            order.setOrderUser(userMapper.selectOneWithPrivate(new User(order.getUserId())));

            // 设置订单详细信息, 包含 摄影师/编剧/套餐/同款作品信息
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(order.getId());
            orderDetail = orderDetailService.get(orderDetail);

            if (orderDetail.getCombo() != null) {
                orderDetail.setOrderCombo(orderComboMapper.selectOne(new OrderCombo(orderDetail.getCombo())));
            }

            order.setOrderDetail(orderDetail);

            // 获取发票信息
            OrderReceipt orderReceipt = new OrderReceipt();
            orderReceipt.setOrder(order.getId());
            orderReceipt = orderReceiptMapper.selectOne(orderReceipt);
            if (Optional.ofNullable(orderReceipt).isPresent()) {
                order.setOrderReceipt(orderReceipt);
            }
        }

        return order;
    }

    @Override
    public List<Order> list(Page page, Order order) {
        if (page != null) {
            PageHelper.startPage(page.getPageNum(), page.getPageSize());
        }
        List<Order> orders = super.mapper.selectAll(order);
        orders.forEach(t -> {
            // 下单用户
            t.setOrderUser(userMapper.selectOneWithPrivate(new User(t.getUserId())));

            // 设置订单详细信息, 包含 摄影师/编剧/套餐/同款作品信息
            t.getOrderDetail().setPhotoGrapherUser(userMapper.selectOne(new User(t.getOrderDetail().getPhotographer())));
            t.getOrderDetail().setScriptWriterUser(userMapper.selectOne(new User(t.getOrderDetail().getScriptwriter())));

            // 如果指定套餐, 获取套餐信息
            if (t.getOrderDetail().getCombo() != null) {
                t.getOrderDetail().setOrderCombo(orderComboMapper.selectOne(new OrderCombo(t.getOrderDetail().getCombo())));
            }
            // 如果指定同款, 获取同信息
            if (t.getOrderDetail().getSameStyleId() != null) {
                t.getOrderDetail().setSameStyle(videoMapper.selectOne(new Video(t.getOrderDetail().getSameStyleId())));
            }

            // 获取发票信息
            OrderReceipt orderReceipt = new OrderReceipt();
            orderReceipt.setOrder(t.getId());
            orderReceipt = orderReceiptMapper.selectOne(orderReceipt);
            if (Optional.ofNullable(orderReceipt).isPresent()) {
                t.setOrderReceipt(orderReceipt);
            }
        });
        return orders;
    }

    @Override
    public boolean save(Order order) {
        return super.save(order);
    }

    @Override
    public boolean delete(Integer[] ids) {
        // 删除订单, 同时删除订单详情和订单执行信息
        orderDetailMapper.deleteByOrderIdArray(ids);
        orderReceiptMapper.deleteByOrderIdArray(ids);
        return super.mapper.deleteByArrayPrimaryKey(ids) > 0;
    }

    @Override
    public Map create(OrderMake orderMake) throws OperationException {
        Map result = Maps.newHashMap();
        result.put("status", false);

        List resultError = Lists.newArrayList();

        // 检查同款是否存在
        if (orderMake.getTheSameStyleId() != null) {
            Video video = videoMapper.selectOne(new Video(orderMake.getTheSameStyleId()));
            if (video == null) {
                throw new OperationException(StringUtil.translateI18N(messageSource, Constants.Message.VIDEO_INFO_DOES_NOT_EXIST));
            }
            orderMake.setScriptwriter(video.getScriptWriter());
            orderMake.setPhotographer(video.getPhotoGrapher());
        }

        // 校验摄影师、编剧是否存在
        if (orderMake.getPhotographer() != null) {
            User photoGrapher = userMapper.selectOne(new User(orderMake.getPhotographer()));
            if (!Optional.ofNullable(photoGrapher).isPresent()) {
                throw new OperationException(StringUtil.translateI18N(messageSource, Constants.Message.PHOTO_GRAPHER_DOES_NOT_EXIST));
            }
        }
        if (orderMake.getScriptwriter() != null) {
            User scriptWriter = userMapper.selectOne(new User(orderMake.getScriptwriter()));
            if (!Optional.ofNullable(scriptWriter).isPresent()) {
                throw new OperationException(StringUtil.translateI18N(messageSource, Constants.Message.SCRIPT_WRITER_DOES_NOT_EXIST));
            }
        }

        // 检查优惠券
        DiscountCoupon discountCoupon = null;
        if (orderMake.getDiscountcouponId() != null) {
            discountCoupon = discountCouponMapper.selectOne(new DiscountCoupon(orderMake.getDiscountcouponId(), WebUtil.getCurrentUser().getId()));
            if (discountCoupon == null) {
                throw new OperationException(StringUtil.translateI18N(messageSource, Constants.Tip.DISCOUNT_COUPON_NOT_EXIST));
            }
            // 将优惠券状态设置为已使用
            discountCoupon.setStatus(2);
            discountCouponMapper.updateByPrimaryKeySelective(discountCoupon);
        }

        // 检查套餐是否存在
        OrderCombo orderCombo = null;
        if (orderMake.getCombo() != null) {
            orderCombo = orderComboMapper.selectOne(new OrderCombo(orderMake.getCombo()));
            if (orderCombo == null) {
                throw new OperationException(StringUtil.translateI18N(messageSource, Constants.Tip.PLEASE_CHOOSE_COMBO));
            }
        }

        // 计算总价
        BigDecimal price = new BigDecimal(0);

        /**
         * 一、 转换为持久层数据
         */
        // (1). 订单
        Order order = new Order();
        order.setNo(order.createOrderNo());
        order.setUserId(WebUtil.getCurrentUser().getId());
        order.setOrderTime(new Date());
        // 1. paid 2. not paid
        order.setStatus(2);
        order.setStatusStep(0);
        // (2). 订单详细
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setGoodsName(Constants.OrderName.getName(orderMake.getType() - 1));
        orderDetail.setVideoType(orderMake.getVideoType());
        orderDetail.setSameStyleId(orderMake.getTheSameStyleId());
        orderDetail.setShootingLocation(orderMake.getLocation());
        orderDetail.setShootingStartDate(orderMake.getExecuteDates()[0]);
        orderDetail.setShootingEndDate(orderMake.getExecuteDates()[1]);
        orderDetail.setRemark(orderMake.getRemark());
        Optional.ofNullable(discountCoupon).ifPresent(t -> {
            order.setDiscount(t.getId());
        });

        // 根据订单类型操作
        switch (orderMake.getType()) {
            // 同款
            case 1:

                // 如果不是宣传片
                if (!orderMake.getVideoType().equals(4)) {

                    orderDetail.setCombo(orderMake.getCombo());
                    price = price.add(orderCombo.getPrice());

                    if (discountCoupon != null) {
                        price = price.subtract(discountCoupon.getPrice());
                    }
                }

                break;

            // 私人订制
            case 2:
                // 设置为待付款-未定价待评估状态
                order.setStatusStep(1);
                // 设置摄影师和编剧
                orderDetail.setPhotographer(orderMake.getPhotographer());
                orderDetail.setScriptwriter(orderMake.getScriptwriter());
                break;

            default:
                break;
        }

        // 根据作品类型操作
        switch (orderMake.getVideoType()) {
            case 1:
                break;
            case 2:
                break;
            case 3:
                break;

            // 宣传片
            case 4:
                // 设置为待付款-未定价待评估状态
                order.setStatusStep(1);
                break;

            default:
                break;
        }

        order.setTotalPrice(price);
        order.setType(orderMake.getType());
        order.setRemark(orderMake.getRemark());

        /**
         * 二、保存订单数据
         */
        save(order);

        /**
         * 三、添加订单详情
         */
        orderDetail.setOrderId(order.getId());
        orderDetail.setGoodsPrice(price);
        orderDetailService.save(orderDetail);

        // 四、添加发票
        if (orderMake.isNeedReceipt()) {
            // 验证发票信息
            // 如果是公司
            if (orderMake.getReceiptHeadType().equals(2)) {
                if (StringUtils.isBlank(orderMake.getDutyNo())) {
                    resultError.add(new Key("dutyNo", "请输入税号"));
                }
                if (StringUtils.isBlank(orderMake.getReceiptHead())) {
                    resultError.add(new Key("receiptHead", "请输入发票抬头"));
                }
            }
            if (StringUtils.isBlank(orderMake.getReceiveName())) {
                resultError.add(new Key("receiveName", "请输入接收发票人"));
            }
            if (StringUtils.isBlank(orderMake.getContactPhone())) {
                resultError.add(new Key("contactPhone", "请输入联系电话"));
            }
            if (orderMake.getReceiptType().equals(1)) {
                if (orderMake.getPostAddress() == null  || StringUtils.isBlank(orderMake.getPostStreet())) {
                    resultError.add(new Key("postAddress", "请输入邮寄地址"));
                }
            }
            if (resultError.size() > 0) {
                result.put("error", resultError);
                return result;
            }
            OrderReceipt orderReceipt = new OrderReceipt();
            orderReceipt.setOrder(order.getId());
            orderReceipt.setType(orderMake.getReceiptType());
            orderReceipt.setTitleType(orderMake.getReceiptHeadType());

            orderReceipt.setUnitName(orderMake.getReceiptHead());
            orderReceipt.setDutyNo(orderMake.getDutyNo());
            orderReceipt.setContent(orderMake.getReceiptContent());

            orderReceipt.setReceiveName(orderMake.getReceiveName());
            orderReceipt.setContactPhone(orderMake.getContactPhone());
            orderReceipt.setContactEmail(orderMake.getContactEmail());

            orderReceipt.setPostAddress(orderMake.getPostAddress());
            orderReceipt.setPostStreet(orderMake.getPostStreet());

            // 已申请
            orderReceipt.setStatus(1);
            orderReceiptService.save(orderReceipt);
        }

        if (resultError.size() > 0) {
            result.put("error", resultError);
            return result;
        }

        result.put("orderId", order.getId());
        result.put("status", true);
        return result;
    }

    @Override
    public Map validate(Map param) throws OperationException {
        param.put("status", "success");
        return param;
    }

    @Override
    public boolean status(Integer orderId, Integer status) throws Exception {
        return super.mapper.status(orderId, status) > 0;
    }
}
